#include "app_buffer.h"
#include <stdlib.h>
#include <string.h>
#include "log/log.h"

//定义一个初始化锁
static pthread_mutex_t init_lock = PTHREAD_MUTEX_INITIALIZER;


/**
 * @brief 初始化缓存
 * @param size 缓存大小
 * @return Buffer* 缓存指针
 */
Buffer *app_buffer_init(int size)
{
    //检查参数的合法性
    if (size <= 0)
    {
        log_error("buffer size must be greater than 0");
        return NULL;
    }

    

    //分配Buffer的内存
    Buffer *buffer = malloc(sizeof(Buffer));
    if (buffer == NULL) 
    {
        log_error("malloc buffer failed");
        return NULL;
    }

    //初始化Buffer的data属性
    buffer->data = malloc(size);
    if (buffer->data == NULL)
    {
        log_error("malloc buffer data failed");
        free(buffer);
        return NULL;
    }
    //初始化Buffer的其他属性
    buffer->total_size = size;
    buffer->len = 0;
    buffer->offset = 0;

    //初始化buffer的lock属性
    buffer->lock = init_lock;

    return buffer;
}


/**
 * @brief 释放缓存
 * @param buffer 缓存指针
 * @return void
 */
void app_buffer_free(Buffer *buffer)
{
    //检查参数的合法性
    if (buffer == NULL)
    {
        log_error("buffer is null");
        return;
    }
    //释放Buffer的data属性
    if (buffer->data != NULL)
    {
        free(buffer->data);
    }
    //释放Buffer的内存
    free(buffer);
}

/**
 * @brief 向缓存中写入数据
 * @param buffer 缓存指针
 * @param data 数据指针
 * @param len 数据长度
 * @return int 0:成功，-1:失败（剩余空间不够了）
 */
int app_buffer_write(Buffer *buffer, void *data, int len)
{
    //检查参数的合法性
    if (buffer == NULL || data == NULL || len <= 0)
    {
        log_error("buffer or data is null or len <= 0");
        return -1;
    }

    //加锁
    pthread_mutex_lock(&buffer->lock);

    //检查buffer剩余空间是否足够
    if (buffer->total_size - buffer->len < len)
    {
        log_error("buffer space is not enough");
        //解锁
        pthread_mutex_unlock(&buffer->lock);

        return -1;
    }
    //计算写入位置
    int write_start = buffer->offset + buffer->len;
    //修正write_start
    if (write_start >= buffer->total_size)
    {
        write_start -= buffer->total_size;
    }
    //将数据写入buffer
    if (write_start + len <= buffer->total_size) //写一段
    {
        memcpy(buffer->data + write_start, data, len);
    }
    else //写两段
    {
        //计算第一段的长度
        int len1 = buffer->total_size - write_start;
        memcpy(buffer->data + write_start, data, len1);
        memcpy(buffer->data, data + len1, len - len1);
        
    }
    buffer->len += len;

    //解锁
    pthread_mutex_unlock(&buffer->lock);

    log_debug("write success offset: %d, len: %d,data: %s",
              buffer->offset, buffer->len, buffer->data);

    return 0;
}

/**
 * @brief 从缓存中读取数据
 * @param buffer 缓存指针
 * @param data 数据指针
 * @param len 要读取数据长度
 * @return int 0:成功，-1:失败（剩余数据不够了）
 */
int app_buffer_read(Buffer *buffer, void *data, int len)
{
    //检查参数的合法性
    if (buffer == NULL || data == NULL || len <= 0)
    {
        log_error("buffer or data is null or len <= 0");
        return -1;
    }

    //加锁
    pthread_mutex_lock(&buffer->lock);

    //检查buffer剩余数据是否足够
    if (buffer->len < len)
    {
        log_error("buffer data is not enough");
        //解锁
        pthread_mutex_unlock(&buffer->lock);

        return -1;
    }

    //从缓存中读取数据
    if (buffer->offset + len <= buffer->total_size)    //读一段
    {
        memcpy(data, buffer->data + buffer->offset, len);
        //更新buffer的offset属性
        buffer->offset += len;

    }
    else    //读两段
    {
        //计算第一段的长度
        int len1 = buffer->total_size - buffer->offset;
        //读取第一段
        memcpy(data, buffer->data + buffer->offset, len1);
        //读取第二段
        memcpy(data + len1, buffer->data, len - len1);
        //更新buffer的offset属性
        buffer->offset = len - len1;
    }
    //更新buffer的len属性
    buffer->len -= len;

    //解锁
    pthread_mutex_unlock(&buffer->lock);

    log_debug("read success offset: %d, len: %d,data: %s",
              buffer->offset, buffer->len, buffer->data);
    

    return 0;
}
